<!doctype html><html lang=cn-zh><head><meta charset=UTF-8><meta name=viewport content="width=device-width,initial-scale=1"><meta http-equiv=X-UA-Compatible content="IE=edge"><style type=text/css>body{font-family:monospace}</style><title>beanstalkd消息队列</title>
<meta name=description content="A blog maintained by Vimiix."><link rel=stylesheet href=/css/style.css><script>var _hmt=_hmt||[];(function(){var e,t=document.createElement("script");t.src="https://hm.baidu.com/hm.js?7c24231917964240bae97e813810620c",e=document.getElementsByTagName("script")[0],e.parentNode.insertBefore(t,e)})()</script></head><body><header>====================<br>== Hi, I'm Vimiix ==<br>====================<div style=float:right;color:gray;font-size:x-large>Get hands dirty.</div><br><p><nav><a href=https://www.vimiix.com/><b>首页</b></a>.
<a href=/posts/><b>文章列表</b></a>.
<a href=/projects/><b>开源项目</b></a>.
<a href=/tags/><b>标签</b></a>.
<a href=/friends/><b>友链</b></a>.
<a href=/about/><b>关于我</b></a>.
<a href=/index.xml><b>RSS</b></a>.</nav></p></header><main><article><h1>beanstalkd消息队列</h1><b><time>2020.03.11 16:22</time></b>
<a href=/tags/beanstalkd>beanstalkd</a>
<a href=/tags/note>note</a>
<a href=/tags/python>Python</a>
<a href=/tags/mq>MQ</a><div><p>beanstalkd 是一个简单快速的分布式工作队列系统，协议基于 ASCII 编码运行在 tcp 上。其最初设计目的是通过后台异步执行耗时任务方式降低高容量 Web 应用的页面延时。而其简单、轻量、易用等特点，和对任务优先级、延时/超时重发等控制，以及<a href=https://github.com/beanstalkd/beanstalkd/wiki/Client-Libraries>众多语言版本的客户端</a>的良好支持，使其可以很好的在各种需要队列系统的场景中应用。</p><p>Beanstalk 的应用场景主要有：</p><ul><li>消息异步处理（消息队列的基本需求）</li><li>消息延迟处理，实现循环队列</li></ul><h3 id=beanstalkd-核心组件>beanstalkd 核心组件</h3><ul><li><code>job</code> : 任务，队列中的基本单元</li><li><code>tube</code> : 一个有名称的任务队列，用来存储统一类型的 <code>job</code> ,beanstalkd 通过 <code>tube</code> 来实现多任务队列</li><li><code>producer</code> : <code>job</code> 生产者，通过<code>put</code>命令来创建一个<code>job</code>放到一个<code>tube</code>中</li><li><code>comsumer</code> : <code>job</code> 消费者，通过 <code>reserve</code>、<code>release</code>、<code>bury</code>、<code>delete</code>命令来获取或改变 <code>job</code> 的状态</li></ul><h3 id=job-的生命周期>job 的生命周期</h3><p>在整个生命周期中 job 可能有四种工作状态：<code>READY</code>、<code>RESERVED</code>、<code>DELAYED</code>、<code>BURIED</code>. 只有处于 <code>READY</code> 状态的 job 才能被消费。</p><pre tabindex=0><code> put with delay            release with delay
  -------------&gt; [DELAYED] &lt;---------.
                     |                   |
                     | (time passes)     |
                     |                   |
   put               v     reserve       |       delete
  --------------&gt; [READY] -------&gt; [RESERVED] ------&gt; *poof*
                     ^  ^                |  |
                     |   \  release      |  |
                     |    `-------------&#39;   |
                     |                      |
                     | kick                 |
                     |                      |
                     |       bury           |
                  [BURIED] &lt;---------------&#39;
                     |
                     |  delete
                      `--------&gt; *poof*
</code></pre><p>Producer 创建 job 的时候可以选择两种方式：<code>put</code> , <code>put with delay</code>。</p><p>当 producer 直接 <code>put</code> 一个 job 时，job 就处于 <code>READY</code> 状态，等待 consumer 来处理，如果选择 <code>put with delay</code>，job 的初始状态为 <code>DELAYED</code> 状态，等待延迟时间过后才迁移到 READY 状态。两种创建 job 的方式都会传入一个 TTR（Timeout 机制），当 job 处于 <code>RESERVED</code> 状态时，TTR 开始倒计时。如果 TTR 倒计时完，job 状态还没有变，就可以认为 job 处理失败，会被重新放回队列。</p><p>consumer 获取（reserve）了一个 READY 的 job 后，该 job 的状态就迁移到 <code>RESERVED</code>。这时候，其他的 consumer 就不能再操作该 job 了。当 consumer 完成该 job 后，可以选择 delete , release 或者 bury 操作;</p><ul><li><p>delete 操作，job 从系统消亡，之后不能再获取;</p></li><li><p>release 操作，可以重新把该 job 状态迁移回 <code>READY</code> ，使其他的 consumer 可以继续获取和执行该 job，也可以延迟（release with delay）该状态迁移操作，这样会中间会多一步 <code>DELAYED</code> 状态的转换。</p></li><li><p>bury 操作，可以把该 job 休眠，等到需要的时候，再将休眠的 job 通过 kick 命令迁移回 <code>READY</code> 状态，也可以通过 delete 销毁 <code>BURIED</code> 状态的 job。</p></li></ul><p>正是有这些有趣的操作和状态，才可以开篇提到的多种应用场景，比如要实现类似 crontab 功能的循环队列，就可以将 <code>RESERVED</code> 状态的 job 休眠掉，等没有 <code>READY</code> 状态的 job 时再将 <code>BURIED</code> 状态的 job 一次性 kick 回 <code>READY</code> 状态。</p><p>为什么要有 <code>BURIED</code> 状态？一个是可以实现 job 不依赖延迟的重复使用，以实现循环队列的功能，另一方面，这其实也可以作为一种异常捕获机制，比如对于前面处理超时的 job，我们就可以将其设置为 <code>BURY</code> 状态，这样有两个好处：</p><ol><li>避免重新放回队列，导致主流程再次进入到异常</li><li>方便后期人工排查错误</li></ol><h3 id=beanstalkd-的一些特性>beanstalkd 的一些特性</h3><ul><li>优先级，producer 产生的任务可以给他分配一个优先级，支持 0 到 2^32 的优先级，值越小，优先级越高，默认优先级为 1024。优先级高的会被消费者首先执行</li><li>持久化，可以通过 binlog 将 job 及其状态记录到文件里面，在 beanstalkd 下次启动时可以通过读取 binlog 来恢复之前的 job 及状态</li><li>分布式，分布式设计和 Memcached 类似，beanstalkd 各个 server 之间并不知道彼此的存在，都是通过 client 来实现分布式以及根据 tube 名称去特定 server 获取 job</li><li>超时机制，为了防止某个 consumer 长时间占用任务但不能处理的情况，beanstalkd 为 reserve 操作设置了 timeout 时间，如果该 consumer 不能在指定时间内完成 job，job 将被迁移回 <code>READY</code> 状态，供其他 consumer 执行。</li></ul><h3 id=一些链接>一些链接</h3><ul><li>beanstalkd 源码地址： <a href=https://github.com/beanstalkd/beanstalkd>https://github.com/beanstalkd/beanstalkd</a></li><li>各编程语言客户端列表：<a href=https://github.com/beanstalkd/beanstalkd/wiki/Client-Libraries>https://github.com/beanstalkd/beanstalkd/wiki/Client-Libraries</a></li><li>beanstalkd 中文协议：<a href=https://github.com/beanstalkd/beanstalkd/blob/master/doc/protocol.zh-CN.md>https://github.com/beanstalkd/beanstalkd/blob/master/doc/protocol.zh-CN.md</a></li></ul></div></article></main><aside><div><div><h3>LATEST POSTS</h3></div><div><ul><li><a href=/posts/2025-10-16-kubernetes-apiserver-authorization-mechanism/>Kubernetes APIServer 鉴权机制</a></li><li><a href=/posts/2025-09-30-kubernetes-apiserver-authentication-mechanism/>Kubernetes APIServer 认证机制</a></li><li><a href=/posts/2024-12-16-deploy-kubernetes-by-kubeadm/>使用 kubeadm 搭建 kubernetes 集群</a></li><li><a href=/posts/2024-09-20-how-to-code-review/>如何做code review</a></li><li><a href=/posts/2024-08-12-weakref-in-python/>Python中的弱引用</a></li></ul></div></div></aside><footer><p>Social Links:
<a href=https://github.com/vimiix><b>Github</b></a>.
<a href=https://www.douban.com/people/vimiix/><b>Douban</b></a>.
<a href=mailto:i@vimiix.com><b>Email</b></a>.<br><hr>&copy; 2017-2025
Vimiix Yao; All rights reserved.
<a href=https://beian.miit.gov.cn/>京ICP备19015214号-1</a></p><script src=https://l2dwidget.js.org/lib/L2Dwidget.min.js></script><script>L2Dwidget.init({model:{jsonPath:"https://unpkg.com/live2d-widget-model-tororo@1.0.5/assets/tororo.model.json"}})</script></footer></body></html>